//#include "StdAfx.h"
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include <stdlib.h>

static const char* const copyright = "Irrlicht Engine (c) 2002-2008 Nikolaus Gebhardt";
	#ifdef _IRR_XBOX_PLATFORM_
		#include <xtl.h>
	#endif

#ifdef _IRR_WINDOWS_
	#include <windows.h>
	#if defined(_DEBUG) && !defined(__GNUWIN32__) && !defined(_WIN32_WCE)
		#include <crtdbg.h>
	#endif // _DEBUG
#endif

#ifdef _IRR_XBOX_PLATFORM_
	#include <xtl.h>
#endif

#include "irrTypes.h"

inline bool IsPowerOf2(int value)
{
	return value && !(value & (value - 1));
}

template <typename T>
inline T RoundUp(T x, unsigned int base)
{
	_IRR_DEBUG_BREAK_IF(!IsPowerOf2(base));

	return static_cast<T>( (x + (base - 1)) & ~(base - 1) );
}

#undef irrnew

void* IrrAlloc(size_t size, MemHint hint);
void IrrFree(void* p);

void* operator new(size_t size, MemHint hint) {
	return IrrAlloc(size, hint);
}
void* operator new[](size_t size, MemHint hint) {
	return IrrAlloc(size, hint);
}
void operator delete(void* p, MemHint hint) {
	IrrFree(p);
}
void operator delete[](void* p, MemHint hint) {
	IrrFree(p);
}

#if 0
#if defined(_IRR_COMPILE_WITH_PS3_)
void *operator new(std::size_t size) throw(std::bad_alloc)
{
	return IrrAlloc(size, MEMHINT_NONE);
}
void *operator new(std::size_t size, const std::nothrow_t&) throw()
{
	return IrrAlloc(size, MEMHINT_NONE);
}
void *operator new[](std::size_t size) throw(std::bad_alloc)
{
	return IrrAlloc(size, MEMHINT_NONE);
}
void *operator new[](std::size_t size, const std::nothrow_t&) throw()
{
	return IrrAlloc(size, MEMHINT_NONE);
}
void operator delete  (void *p) throw(){
	IrrFree(p);
}
void operator delete[](void *p) throw(){
	IrrFree(p);
}
void operator delete  (void *p, const std::nothrow_t&) throw(){
	IrrFree(p);
}
void operator delete[](void *p, const std::nothrow_t&) throw(){
	IrrFree(p);
}
void operator delete  (void *p, void *) throw(){
	IrrFree(p);
}
void operator delete[](void *p, void *) throw(){
	IrrFree(p);
}
#endif
#endif

extern "C" void *irr_malloc(size_t size)
{
	return IrrAlloc(size, MEMHINT_NONE);
}

extern "C" void *irr_free(void* p)
{
	IrrFree(p);
	return 0;
}

void* IrrAlloc(size_t size, MemHint hint, int block, const char* filename, int line);

void* operator new(size_t size, MemHint hint, int block, const char* filename, int line) {
	return IrrAlloc(size, hint, block, filename, line);
}
void* operator new[](size_t size, MemHint hint, int block, const char* filename, int line) {
	return IrrAlloc(size, hint, block, filename, line);
}
void operator delete(void* p, MemHint hint, int block, const char* filename, int line) {
	IrrFree(p);
}
void operator delete[](void* p, MemHint hint, int block, const char* filename, int line) {
	IrrFree(p);
}


#if defined(_IRR_STATIC_LIB_) && !defined(_IRR_WII_EMULATION_) && !defined(_IRR_USE_DEFAULT_ALLOCATOR_)

//both these functions need to be implemented game side

//void* IrrAlloc(size_t size, MemHint hint) 
//void IrrFree(void* p, MemHint hint)
//void* IrrAlloc(size_t size, MemHint hint, int block, const char* filename, int line) ;

#else

void* IrrAlloc(size_t size, MemHint hint, int block, const char* filename, int line)
{
	return IrrAlloc(size, hint);
}

void* IrrAlloc(size_t size, MemHint hint) 
{
	return malloc(size);
}

void IrrFree(void* p)
{
	free(p);
}

#endif



#if (defined(_IRR_WINDOWS_API_)||defined(_IRR_XBOX_PLATFORM_)) && !defined(_IRR_STATIC_LIB_) 

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved )
{
	// _crtBreakAlloc = 139;

    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			/*#if defined(_DEBUG) && !defined(__GNUWIN32__) && !defined(__BORLANDC__) && !defined (_WIN32_WCE)
				_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
			#endif*/
			break;
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

#endif // defined(_IRR_WINDOWS_)

int WCSLEN( const WCHAR_T* _Str )
{
	int i = 0;
	while( _Str[i] ) i++;
	return i;
}

WCHAR_T* WCSCPY( WCHAR_T* _Dest, const WCHAR_T* _Source )
{
	int i = 0;
	while( _Source[i] )
	{
		_Dest[i] = _Source[i];
		i++;
	}

	_Dest[i] = 0;

	return _Dest;
}

int WCSCMP( const WCHAR_T* _Str1, const WCHAR_T* _Str2 )
{
	int i = 0;
	while( _Str1[i] && _Str2[i] && _Str1[i] == _Str2[i] ){i++;};
	if( _Str1[i] == _Str2[i] )
	{
		return 0;
	}
	return ((_Str1[i] < _Str2[i])?-1:1);
}

WCHAR_T* WCSCAT( WCHAR_T* _Dest, const WCHAR_T* _Source )
{
	return WCSCPY( _Dest + WCSLEN(_Dest), _Source );
}

int WCSTOMBS_S( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const WCHAR_T *wcstr, size_t count )
{
	if( !mbstr && sizeInBytes > 0 )
	{
		*pReturnValue = 0;
		return -1;
	}

	if( !wcstr )
	{
		*pReturnValue = 0;
		return -2;
	}

	*pReturnValue = 0;
	while ( wcstr[*pReturnValue] && *pReturnValue < (count - 1) )
	{
		if( *pReturnValue >= (sizeInBytes - 1) )
		{
			mbstr[(*pReturnValue)++] = 0;
			return -3;
		}
		mbstr[*pReturnValue] = wcstr[*pReturnValue];
		(*pReturnValue)++;
	}

	mbstr[(*pReturnValue)++] = 0;
	

	return 0;
}

#ifdef SC5_DEBUG_FPS

DebugInfo	g_debugInfo[] =
{
	{ 1,		"FPS_NV_PARAMS" },
	{ 1,		"FPS_SET_MAT_TYPE_AND_COLOR" },
	{ 1,		"FPS_RENDER_GUARDS" },
	{ 1,		"FPS_RENDER_GUARD_SHADOWS" },
	{ 1,		"FPS_RENDER_GUARD_ENVIRONMENT" },
	{ 1,		"FPS_RENDER_REGISTER_SCENE_MODE" },
	{ 1,		"FPS_RENDER_CAMERA_SCENES" },
	{ 1,		"FPS_RENDER_LIGHTS_SCENES" },
	{ 1,		"FPS_RENDER_SKYBOX" },
	{ 1,		"FPS_RENDER_SOLID_NODES" },
	{ 1,		"FPS_RENDER_SPECIAL_ENEMY_FOG" },
	{ 1,		"FPS_RENDER_SECONDARY_SKYBOX" },
	{ 1,		"FPS_RENDER_SHADOWS" },
	{ 1,		"FPS_RENDER_STENCIL_SHADOWS" },
	{ 1,		"FPS_RENDER_TRANSPARENT_OBJECTS" },
	{ 1,		"FPS_RENDER_CAMERA_LIST" },
	{ 1,		"FPS_RENDER_RESET_CAMERA" },
	{ 1,		"FPS_RENDER_CLEAR_ZBUFFER" },
	{ 1,		"FPS_RENDER_OVERLAYS" },
	{ 1,		"FPS_RENDER_NV_SUPPORT" },
	{ 1,		"FPS_SCENE_MANAGER_UPDATE" },
	{ 1,		"FPS_UPDATE_WORLD_VOICES" },
	{ 1,		"FPS_UPDATE_WORLD_TICKET_GRENADE" },
	{ 1,		"FPS_UPDATE_WORLD_ADD_CINEMATIC" },
	{ 1,		"FPS_UPDATE_WORLD_INTERF_COLOR" },
	{ 1,		"FPS_UPDATE_WORLD_TUTORIALS" },
	{ 1,		"FPS_UPDATE_WORLD_SPECIAL_VISION" },
	{ 1,		"FPS_UPDATE_WORLD_GUARDMGR_PREUPDATE" },
	{ 1,		"FPS_UPDATE_WORLD_GUARDMGR_POSTUPDATE" },
	{ 1,		"FPS_UPDATE_WORLD_THROWABLES" },
	{ 1,		"FPS_UPDATE_WORLD_DETECTION_INDICATOR" },
	{ 1,		"FPS_UPDATE_WORLD_CINEMATIC_MANAGER" },
	{ 1,		"FPS_UPDATE_WORLD_CAMERA_MODE" },
	{ 1,		"FPS_UPDATE_WORLD_CAMERA" },
	{ 1,		"FPS_UPDATE_WORLD_GRENADE_TRAJECTORY" },
	{ 1,		"FPS_UPDATE_WORLD_WEATHER_MANAGER" },
	{ 1,		"FPS_UPDATE_WORLD_PARTICLE_MANAGER" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP1" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP1_1" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP1_2" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP1_3" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP2" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP3" },
	{ 1,		"FPS_UPDATE_GAME_OBJECTS_STEP4" },
	{ 1,		"FPS_DRAW_2D_RECTANGLE" },
	{ 1,		"FPS_DRAW_FADE_ANIM" },
	{ 1,		"FPS_DRAW_GUARDS_ARROWS" },
	{ 1,		"FPS_DRAW_OBJECTIVES_ARROWS" },
	{ 1,		"FPS_DRAW_VISION_OVERLAY" },
	{ 1,		"FPS_DRAW_GLOW_LENSFLARE" },
	{ 1,		"FPS_DRAW_LOW_HEALTH_EFFECT" },
	{ 1,		"FPS_DRAW_DAMAGE_EFFECT" },
	{ 1,		"FPS_DRAW_GRENADE_THREATS" },
	{ 1,		"FPS_DRAW_CAMERA_OVERLAY" },
	{ 1,		"FPS_DRAW_MARK_AND_EXECUTE" },
	{ 1,		"FPS_DRAW_MINIMAP" },
	{ 1,		"FPS_DRAW_MINIMESSAGE" },
	{ 1,		"FPS_DRAW_MESSAGE_MANAGER" },
	{ 1,		"FPS_DRAW_PLAYER_CONTROLS" },
	{ 1,		"FPS_DRAW_TARGET" },
	{ 1,		"FPS_DRAW_QTES" },
	{ 1,		"FPS_DRAW_2D_DEBUG" },
	{ 1,		"FPS_DRAW_WORLD" },
	{ 1,		"FPS_DRAW_DECALS" },
	{ 1,		"FPS_RENDER_3D_ROOM_UPDATE" },
	{ 1,		"FPS_RENDER_3D_DRAWGAMEOBJECTS" },
	{ 1,		"FPS_RENDER_3D_SCENEMANAGER_DRAWALL" },
};
int g_debugInfoCount = sizeof(g_debugInfo) / sizeof(DebugInfo);

#endif //SC5_DEBUG_FPS
